//*************************************************************************************
//* 作    者： 邹杭特
//* 创建时间： 2021-12-17 12:51:15
//* 描    述： 本地设置控制

//* ************************************************************************************
using System.Collections.Generic;
using UFrame.DataStore;

namespace UFrame.Setting
{
    public class LocalStoreSettingCtrl : BaseSettingCtrl
    {
        private SettingSerialize m_serialize = new SettingSerialize();
        private DataStoreCtrl m_storeCtrl = new DataStoreCtrl();
        private Dictionary<int, int> m_intValues = new Dictionary<int, int>();
        private Dictionary<int, float> m_floatValues = new Dictionary<int, float>();
        private string m_settingKey;

        public void Initialize(string fileName)
        {
            m_storeCtrl.OnRegist();
            m_settingKey = fileName;
            var storeStr = m_storeCtrl.GetString(fileName);
            if (!string.IsNullOrEmpty(storeStr))
            {
                ClearAll(m_serialize);
                ParseFromJson(m_serialize,storeStr);
            }
        }
        
        public override string SerializeToJson()
        {
            if (m_serialize != null)
            {
                return SerializeToJson(m_serialize);
            }
            return null;
        }

        public override void ClearAll()
        {
            base.ClearAll();
            ClearAll(m_serialize);
            m_storeCtrl.ClearAllData();
            m_intValues.Clear();
            m_floatValues.Clear();
        }

        public override bool TryGetFloat(int settingID, out float value)
        {
            if (m_floatValues.TryGetValue(settingID, out value))
            {
                return true;
            }
            if (TryGetFloat(m_serialize, settingID, out value) )
            {
                m_floatValues[settingID] = value;
                return true;
            }
            return false;
        }

        public override bool TryGetInt(int settingID, out int value)
        {
            if (m_intValues.TryGetValue(settingID, out value))
            {
                return true;
            }
            if (TryGetInt(m_serialize,settingID, out value))
            {
                m_intValues[settingID] = value;
                return true;
            }
            return false;
        }

        public override bool TryGetString(int settingID, out string value)
        {
            if (TryGetString(m_serialize, settingID, out value))
            {
                return true;
            }
            return false;
        }

        protected override bool SetStringOnly(int settingID, string value)
        {
            var info = m_serialize.s.Find(x => x.k == settingID);
            if (info == null)
            {
                info = new SettingSerialize.SettingNode(settingID, value);
                m_serialize.s.Add(info);
            }
            else
            {
                info.v = value;
            }
            return true;
        }

        protected override bool SetFloatOnly(int settingID, float value)
        {
            m_floatValues[settingID] = value;
            var strValue = value.ToString("0.00");
            var info = m_serialize.f.Find(x => x.k == settingID);
            if (info == null)
            {
                info = new SettingSerialize.SettingNode(settingID, strValue);
                m_serialize.f.Add(info);
            }
            else
            {
                info.v = strValue;
            }
            return true;
        }

        protected override bool SetIntOnly(int settingID, int value)
        {
            m_intValues[settingID] = value;
            var info = m_serialize.i.Find(x => x.k == settingID);
            if (info == null)
            {
                info = new SettingSerialize.SettingNode(settingID, value.ToString());
                m_serialize.i.Add(info);
            }
            else
            {
                info.v = value.ToString();
            }
            return true;
        }

        protected override void DoSave()
        {
            if (m_storeCtrl != null && m_serialize != null && !string.IsNullOrEmpty(m_settingKey))
            {
                var dataJson = SerializeToJson(m_serialize);
                m_storeCtrl.SetString(m_settingKey, dataJson);
            }
        }

        public override void ParseFromJson(string json)
        {
            if (!string.IsNullOrEmpty(json))
            {
                ClearAll(m_serialize);
                if (ParseFromJson(m_serialize,json))
                {
                    m_storeCtrl.SetString(m_settingKey, json);
                }
            }
        }

        private void ClearAll(SettingSerialize serialize)
        {
            serialize.i.Clear();
            serialize.f.Clear();
            serialize.s.Clear();
        }

        private string SerializeToJson(SettingSerialize serialize)
        {
            return UnityEngine.JsonUtility.ToJson(serialize);
        }

        private bool ParseFromJson(SettingSerialize serialize, string json)
        {
            UnityEngine.JsonUtility.FromJsonOverwrite(json, serialize);
            return true;
        }

        private bool TryGetString(SettingSerialize serialize, int settingID, out string value)
        {
            var info = serialize.s.Find(x => x.k == settingID);
            if(info != null)
            {
                value = info.v;
                return true;
            }
            value = null;
            return false;
        }

        private bool TryGetFloat(SettingSerialize serialize, int settingID, out float value )
        {
            var info = serialize.f.Find(x => x.k == settingID);
            if (info != null && float.TryParse(info.v,out value))
            {
                return true;
            }
            value = 0;
            return false;
        }

        private bool TryGetInt(SettingSerialize serialize, int settingID, out int value)
        {
            var info = serialize.i.Find(x => x.k == settingID);
            if (info != null && int.TryParse(info.v, out value))
            {
                return true;
            }
            value = 0;
            return false;
        }
    }
}